import java.util.Random;

public final class Font extends Renderer2D {
	public boolean isBold;
	public byte[][] pixels;
	public int offset;
	public int[] widths;
	public int[] heights;
	public int[] drawOffsetsX;
	public int[] drawOffsetsY;
	public int[] screenWidths;
	public Random randomGenerator;

	/**
	 * Draws text.
	 * 
	 * @param message
	 *            The message.
	 * @param x
	 *            The x position.
	 * @param y
	 *            The y position.
	 * @param color
	 *            The color of the text.
	 */
	public void drawCenteredText(String message, int x, int y, int color) {
		drawText(message, x - getAlphaNumericTextWidth(message) / 2, y, color);
	}

	/**
	 * Gets the hex color code for colors such as @blu@
	 * 
	 * @param color
	 * @return
	 */
	private int getColorByName(String color) {
		/**
		 * Hexadecimal color code use as @##@
		 * 
		 * @syntax @123@ = 0x112233
		 */
		if (color.equals("369")) {
			return 0x336699;
		}
		if (color.equals("mon")) {
			return 0x00ff80;
		}
		if (color.equals("red")) {
			return 0xff0000;
		}
		if (color.equals("gre")) {
			return 65280;
		}
		if (color.equals("blu")) {
			return 255;
		}
		if (color.equals("yel")) {
			return 0xffff00;
		}
		if (color.equals("cya")) {
			return 65535;
		}
		if (color.equals("mag")) {
			return 0xff00ff;
		}
		if (color.equals("whi")) {
			return 0xffffff;
		}
		if (color.equals("bla")) {
			return 0;
		}
		if (color.equals("lre")) {
			return 0xff9040;
		}
		if (color.equals("dre")) {
			return 0x800000;
		}
		if (color.equals("dbl")) {
			return 128;
		}
		if (color.equals("or1")) {
			return 0xffb000;
		}
		if (color.equals("or2")) {
			return 0xff7000;
		}
		if (color.equals("or3")) {
			return 0xff3000;
		}
		if (color.equals("gr1")) {
			return 0xc0ff00;
		}
		if (color.equals("gr2")) {
			return 0x80ff00;
		}
		if (color.equals("gr3")) {
			return 0x40ff00;
		}
		if (color.equals("str")) {
			isBold = true;
		}
		if (color.equals("end")) {
			isBold = false;
		}
		return -1;
	}

	/**
	 * Gets the text's width.
	 * 
	 * @param text
	 *            The text.
	 * @return
	 */
	public int getTextWidth(String text) {
		if (text == null) {
			return 0;
		}
		int width = 0;
		for (int count = 0; count < text.length(); count++) {
			if ((text.charAt(count) == '@') && (count + 4 < text.length())
			&& (text.charAt(count + 4) == '@')) {
				count += 4;
			} else {
				width += screenWidths[text.charAt(count)];
			}
		}
		return width;
	}

	public void drawLeftAlignedText(String text, int x, int y, int color) {
		drawText(text, x - getAlphaNumericTextWidth(text), y, color);
	}

	public void drawCenteredText(String text, int x, int y, int color, boolean flag) {
		drawText(text, x - getTextWidth(text) / 2, y, color, flag);
	}

	/**
	 * Gets the width of alphanumeric text.
	 * 
	 * @param text
	 *            The text.
	 * @return
	 */
	public int getAlphaNumericTextWidth(String text) {
		if (text == null) {
			return 0;
		}
		int width = 0;
		for (int count = 0; count < text.length(); count++) {
			width += screenWidths[text.charAt(count)];
		}
		return width;
	}

	/**
	 * Draws normal text.
	 * 
	 * @param text
	 *            The text.
	 * @param x
	 *            The x position.
	 * @param y
	 *            The y position.
	 * @param color
	 *            The color code.
	 */
	public void drawText(String text, int x, int y, int color) {
		if (text == null) {
			return;
		}
		y -= offset;
		for (int i = 0; i < text.length(); i++) {
			char c = text.charAt(i);
			if (c != ' ') {
				method392(pixels[c], x + drawOffsetsX[c], y + drawOffsetsY[c], widths[c],
				heights[c], color);
			}
			x += screenWidths[c];
		}
	}

	public void drawWaveText(String message, int x, int y, int color, int k) {
		if (message == null) {
			return;
		}
		x -= getAlphaNumericTextWidth(message) / 2;
		y -= offset;
		for (int i = 0; i < message.length(); i++) {
			char c = message.charAt(i);
			if (c != ' ') {
				method392(pixels[c], x + drawOffsetsX[c], y + drawOffsetsY[c]
				+ (int) (Math.sin(i / 2D + k / 5D) * 5D), widths[c], heights[c], color);
			}
			x += screenWidths[c];
		}
	}

	/**
	 * Draws the "Wave2:" chat effect in game.
	 * 
	 * @param message
	 *            The player's message.
	 * @param x
	 *            The X position of the text.
	 * @param y
	 *            The Y position of the text.
	 * @param color
	 *            The color of the text.
	 * @param k
	 */
	public void drawWave2Text(String message, int x, int y, int color, int k) {
		if (message == null) {
			return;
		}
		x -= getAlphaNumericTextWidth(message) / 2;
		k -= offset;
		for (int i = 0; i < message.length(); i++) {
			char c = message.charAt(i);
			if (c != ' ') {
				method392(pixels[c], x + drawOffsetsX[c] + (int) (Math.sin(i / 5D + y / 5D) * 5D),
				k + drawOffsetsY[c] + (int) (Math.sin(i / 3D + y / 5D) * 5D), widths[c],
				heights[c], color);
			}
			x += screenWidths[c];
		}
	}

	/**
	 * Draws the "Shake:" chat effect in game.
	 * 
	 * @param message
	 *            A player's message.
	 * @param x
	 *            The X position.
	 * @param y
	 *            The Y position.
	 * @param i
	 * @param j
	 * @param color
	 */
	public void drawShakeText(String message, int x, int y, int i, int j, int color) {
		if (message == null) {
			return;
		}
		double d = 7D - i / 8D;
		if (d < 0.0D) {
			d = 0.0D;
		}
		x -= getAlphaNumericTextWidth(message) / 2;
		y -= offset;
		for (int k1 = 0; k1 < message.length(); k1++) {
			char c = message.charAt(k1);
			if (c != ' ') {
				method392(pixels[c], x + drawOffsetsX[c], y + drawOffsetsY[c]
				+ (int) (Math.sin(k1 / 1.5D + j) * d), widths[c], heights[c], color);
			}
			x += screenWidths[c];
		}
	}

	/**
	 * Draws shaded text.
	 * 
	 * @param text
	 *            The text.
	 * @param x
	 *            The x position.
	 * @param y
	 *            The y position.
	 * @param color
	 *            The color.
	 * @param shadow
	 *            Shadowing.
	 */
	public void drawText(String text, int x, int y, int color, boolean shadow) {
		isBold = false;
		int l = x;
		if (text == null) {
			return;
		}
		y -= offset;
		for (int i = 0; i < text.length(); i++) {
			if ((text.charAt(i) == '@') && (i + 4 < text.length()) && (text.charAt(i + 4) == '@')) {
				int serverSideColor = getColorByName(text.substring(i + 1, i + 4));
				if (serverSideColor != -1) {
					color = serverSideColor;
				}
				i += 4;
			} else {
				char c = text.charAt(i);
				if (c != ' ') {
					if (shadow) {
						method392(pixels[c], x + drawOffsetsX[c] + 1, y + drawOffsetsY[c] + 1,
						widths[c], heights[c], 0);
					}
					method392(pixels[c], x + drawOffsetsX[c], y + drawOffsetsY[c], widths[c],
					heights[c], color);
				}
				x += screenWidths[c];
			}
		}
		if (isBold) {
			Renderer2D.drawHorizontalLine(l, y + (int) (offset * 0.69999999999999996D), x - l,
			0x800000);
		}
	}

	public void method390(int i, int j, String s, int k, int i1) {
		if (s == null) {
			return;
		}
		randomGenerator.setSeed(k);
		int j1 = 192 + (randomGenerator.nextInt() & 0x1f);
		i1 -= offset;
		for (int k1 = 0; k1 < s.length(); k1++) {
			if ((s.charAt(k1) == '@') && (k1 + 4 < s.length()) && (s.charAt(k1 + 4) == '@')) {
				int l1 = getColorByName(s.substring(k1 + 1, k1 + 4));
				if (l1 != -1) {
					j = l1;
				}
				k1 += 4;
			} else {
				char c = s.charAt(k1);
				if (c != ' ') {
					method394(192, i + drawOffsetsX[c] + 1, pixels[c], widths[c], i1
					+ drawOffsetsY[c] + 1, heights[c], 0);
					method394(j1, i + drawOffsetsX[c], pixels[c], widths[c], i1 + drawOffsetsY[c],
					heights[c], j);
				}
				i += screenWidths[c];
				if ((randomGenerator.nextInt() & 3) == 0) {
					i++;
				}
			}
		}
	}

	private void method392(byte text[], int i, int j, int k, int l, int i1) {
		int j1 = i + j * Renderer2D.width;
		int k1 = Renderer2D.width - k;
		int l1 = 0;
		int i2 = 0;
		if (j < Renderer2D.topY) {
			int j2 = Renderer2D.topY - j;
			l -= j2;
			j = Renderer2D.topY;
			i2 += j2 * k;
			j1 += j2 * Renderer2D.width;
		}
		if (j + l >= Renderer2D.bottomY) {
			l -= ((j + l) - Renderer2D.bottomY);
		}
		if (i < Renderer2D.topX) {
			int k2 = Renderer2D.topX - i;
			k -= k2;
			i = Renderer2D.topX;
			i2 += k2;
			j1 += k2;
			l1 += k2;
			k1 += k2;
		}
		if (i + k >= Renderer2D.bottomX) {
			int l2 = ((i + k) - Renderer2D.bottomX);
			k -= l2;
			l1 += l2;
			k1 += l2;
		}
		if (!((k <= 0) || (l <= 0))) {
			method393(Renderer2D.pixels, text, i1, i2, j1, k, l, k1, l1);
		}
	}

	private void method393(int ai[], byte abyte0[], int i, int j, int k, int l, int i1, int j1,
	int k1) {
		int l1 = -(l >> 2);
		l = -(l & 3);
		for (int i2 = -i1; i2 < 0; i2++) {
			for (int j2 = l1; j2 < 0; j2++) {
				if (abyte0[j++] != 0) {
					ai[k++] = i;
				} else {
					k++;
				}
				if (abyte0[j++] != 0) {
					ai[k++] = i;
				} else {
					k++;
				}
				if (abyte0[j++] != 0) {
					ai[k++] = i;
				} else {
					k++;
				}
				if (abyte0[j++] != 0) {
					ai[k++] = i;
				} else {
					k++;
				}
			}
			for (int k2 = l; k2 < 0; k2++) {
				if (abyte0[j++] != 0) {
					ai[k++] = i;
				} else {
					k++;
				}
			}
			k += j1;
			j += k1;
		}
	}

	private void method394(int i, int j, byte abyte0[], int k, int l, int i1, int j1) {
		int k1 = j + l * Renderer2D.width;
		int l1 = Renderer2D.width - k;
		int i2 = 0;
		int j2 = 0;
		if (l < Renderer2D.topY) {
			int k2 = Renderer2D.topY - l;
			i1 -= k2;
			l = Renderer2D.topY;
			j2 += k2 * k;
			k1 += k2 * Renderer2D.width;
		}
		if (l + i1 >= Renderer2D.bottomY) {
			i1 -= ((l + i1) - Renderer2D.bottomY);
		}
		if (j < Renderer2D.topX) {
			int l2 = Renderer2D.topX - j;
			k -= l2;
			j = Renderer2D.topX;
			j2 += l2;
			k1 += l2;
			i2 += l2;
			l1 += l2;
		}
		if (j + k >= Renderer2D.bottomX) {
			int i3 = ((j + k) - Renderer2D.bottomX);
			k -= i3;
			i2 += i3;
			l1 += i3;
		}
		if ((k <= 0) || (i1 <= 0)) {
			return;
		}
		method395(abyte0, i1, k1, Renderer2D.pixels, j2, k, i2, l1, j1, i);
	}

	private void method395(byte abyte0[], int i, int j, int ai[], int l, int i1, int j1, int k1,
	int l1, int i2) {
		l1 = ((l1 & 0xff00ff) * i2 & 0xff00ff00) + ((l1 & 0xff00) * i2 & 0xff0000) >> 8;
		i2 = 256 - i2;
		for (int j2 = -i; j2 < 0; j2++) {
			for (int k2 = -i1; k2 < 0; k2++) {
				if (abyte0[l++] != 0) {
					int l2 = ai[j];
					ai[j++] = (((l2 & 0xff00ff) * i2 & 0xff00ff00)
					+ ((l2 & 0xff00) * i2 & 0xff0000) >> 8)
					+ l1;
				} else {
					j++;
				}
			}
			j += k1;
			l += j1;
		}
	}

	public Font(boolean flag, String archiveName, Archive archive) {
		pixels = new byte[256][];
		widths = new int[256];
		heights = new int[256];
		drawOffsetsX = new int[256];
		drawOffsetsY = new int[256];
		screenWidths = new int[256];
		randomGenerator = new Random();
		isBold = false;
		Packet data = new Packet(archive.getFile(archiveName + ".dat"));
		Packet index = new Packet(archive.getFile("index.dat"));
		index.offset = data.getUnsignedShort() + 4;
		int k = index.getUnsignedByte();
		if (k > 0) {
			index.offset += 3 * (k - 1);
		}
		for (int character = 0; character < 256; character++) {
			drawOffsetsX[character] = index.getUnsignedByte();
			drawOffsetsY[character] = index.getUnsignedByte();
			int width = widths[character] = index.getUnsignedShort();
			int height = heights[character] = index.getUnsignedShort();
			int type = index.getUnsignedByte();
			int pixels = width * height;
			this.pixels[character] = new byte[pixels];
			if (type == 0) {
				for (int i = 0; i < pixels; i++) {
					this.pixels[character][i] = data.getByte();
				}
			} else if (type == 1) {
				for (int i2 = 0; i2 < width; i2++) {
					for (int i3 = 0; i3 < height; i3++) {
						this.pixels[character][i2 + i3 * width] = data.getByte();
					}
				}
			}
			if ((height > offset) && (character < 128)) {
				offset = height;
			}
			drawOffsetsX[character] = 1;
			screenWidths[character] = width + 2;
			int k2 = 0;
			for (int i3 = height / 7; i3 < height; i3++) {
				k2 += this.pixels[character][i3 * width];
			}
			if (k2 <= height / 7) {
				screenWidths[character]--;
				drawOffsetsX[character] = 0;
			}
			k2 = 0;
			for (int j3 = height / 7; j3 < height; j3++) {
				k2 += this.pixels[character][(width - 1) + j3 * width];
			}
			if (k2 <= height / 7) {
				screenWidths[character]--;
			}
		}
		if (flag) {
			screenWidths[32] = screenWidths[73];
		} else {
			screenWidths[32] = screenWidths[105];
		}
	}
}
